<template>
  <div>
    <el-row
      class="border-rd-4px bg-[#fff]"
      :gutter="0"
      v-if="contentConfig.hasDashData"
    >
      <el-col :span="8" v-for="(item, index) in cardData" :key="index">
        <div class="state-item overflow-hidden">
          <div class="state-left">
            <span class="ellipsis">{{ item.title }}</span>
            <strong>{{ Math.round(item.count) }}</strong>
          </div>
          <!-- <i class="iconfont" :class="[item.bgClass, item.iconClass]"></i> -->
          <svg-icon class="shrink-0" :icon-class="item.iconClass" />
        </div>
      </el-col>
    </el-row>

    <slot name="top-data"></slot>

    <div class="table-box">
      <div
        class="table-tool border-b-1px border-b-solid border-b-[#ECEDF0]"
        v-if="contentConfig.tableName"
      >
        <!-- 表格左上方标题 -->
        <span class="table-title">{{ contentConfig.tableName }}</span>
        <!-- 表格右上方工具栏 -->
        <div class="toolbar-btn">
          <template v-for="item in contentConfig.toolbar" :key="item">
            <template v-if="typeof item === 'string'">
              <!-- 刷新 -->
              <template v-if="item === 'refresh'">
                <el-button
                  type="info"
                  icon="refresh"
                  @click="handleToolbar(item)"
                />
              </template>
              <!-- 新增 -->
              <template v-else-if="item === 'add'">
                <el-button
                  type="primary"
                  icon="plus"
                  @click="handleToolbar(item)"
                >
                  {{ $t("common.new") }}
                </el-button>
              </template>
              <!-- 删除 -->
              <template v-else-if="item === 'delete'">
                <el-button
                  v-hasPerm="[`${contentConfig.pageName}:${item}`]"
                  type="danger"
                  icon="delete"
                  :disabled="removeIds.length === 0"
                  @click="handleToolbar(item)"
                >
                  {{ $t("common.delete") }}
                </el-button>
              </template>
              <!-- 导出 -->
              <template v-else-if="item === 'export'">
                <el-button
                  v-hasPerm="[`${contentConfig.pageName}:${item}`]"
                  type="success"
                  icon="download"
                  @click="handleToolbar(item)"
                >
                  {{ $t("common.export") }}
                </el-button>
              </template>
            </template>
            <!-- 其他 -->
            <template v-else-if="typeof item === 'object'">
              <template v-if="item.auth">
                <el-button
                  v-hasPerm="[`${contentConfig.pageName}:${item.auth}`]"
                  :icon="item.icon"
                  type="default"
                  @click="handleToolbar(item.name)"
                >
                  {{ item.text }}
                </el-button>
              </template>
              <template v-else>
                <el-button
                  :icon="item.icon"
                  type="default"
                  @click="handleToolbar(item.name)"
                >
                  {{ item.text }}
                </el-button>
              </template>
            </template>
          </template>
        </div>
      </div>
      <div
        v-if="contentConfig.tagList"
        class="table-filter flex justify-between items-center pt4 pb4"
      >
        <!-- 表格搜索栏 -->
        <div class="left">
          <div class="searchbar-btn" v-if="contentConfig.searchbar">
            <template v-for="item in contentConfig.searchbar" :key="item">
              <!-- 删除 -->
              <template v-if="item === 'delete'">
                <el-button
                  v-hasPerm="[`${contentConfig.pageName}:${item}`]"
                  type="danger"
                  icon="delete"
                  :disabled="removeIds.length === 0"
                  @click="handleToolbar(item)"
                >
                  {{ $t("common.delete") }}
                </el-button>
              </template>
              <!-- 新增 -->
              <template v-else-if="item === 'add'">
                <el-button
                  type="primary"
                  icon="plus"
                  @click="handleToolbar(item)"
                >
                  {{ $t("common.new") }}
                </el-button>
              </template>
            </template>
          </div>
          <div class="flex gap-2">
            <el-tag
              :type="tag == item.value ? 'primary' : 'info'"
              v-for="item in contentConfig.tagList"
              class="cursor-pointer"
              :key="item.value"
              @click="handleStatus(item.value)"
              >{{ item.label }}</el-tag
            >
          </div>
        </div>

        <el-input
          v-model="searchName"
          style="width: 240px"
          :placeholder="contentConfig?.searchPlaceholder"
        >
          <template #append>
            <el-button @click="handleSearch" :icon="Search" />
          </template>
        </el-input>
      </div>
      <div class="el-table-box">
        <!-- 列表 -->
        <el-table
          v-loading="loading"
          :stripe="stripe"
          :header-cell-style="{
            'background-color': '#F6F7F9',
            color: '#8B8B99',
          }"
          v-bind="contentConfig.table"
          :data="pageData"
          row-key="id"
          :tree-props="{ children: 'childlist', hasChildren: 'hasChildren' }"
          @selection-change="handleSelectionChange"
        >
          <template v-for="col in contentConfig.cols" :key="col.prop">
            <!-- 列操作栏 -->
            <template v-if="col.templet === 'tool'">
              <el-table-column
                :show-overflow-tooltip="col.tooltip"
                :min-width="col.minWidth"
                v-bind="col"
              >
                <template #default="scope">
                  <template v-for="item in col.operat" :key="item">
                    <template v-if="typeof item === 'string'">
                      <!-- 编辑/查看/删除 -->
                      <template
                        v-if="
                          item === 'edit' ||
                          item === 'permissions' ||
                          item === 'addstock' ||
                          item === 'resetpwd' ||
                          item === 'view' ||
                          item === 'delete'
                        "
                      >
                        <!-- v-hasPerm="[`${contentConfig.pageName}:${item}`]" -->
                        <el-button
                          :type="
                            item === 'edit' ||
                            item === 'view' ||
                            item === 'permissions'
                              ? 'primary'
                              : item === 'resetpwd' || item === 'addstock'
                                ? 'warning'
                                : 'danger'
                          "
                          :icon="
                            (item === 'edit' && editRowId == scope.row.id) ||
                            item === 'permissions' ||
                            item === 'addstock' ||
                            item === 'resetpwd'
                              ? ''
                              : item
                          "
                          link
                          @click="
                            handleOperat({
                              name: item,
                              row: scope.row,
                              column: scope.column,
                              $index: scope.$index,
                            })
                          "
                        >
                          <svg-icon
                            v-if="item === 'edit' && editRowId == scope.row.id"
                            icon-class="save"
                            class="mr-6px w-14px h-14px"
                          />
                          <svg-icon
                            v-if="item === 'permissions'"
                            icon-class="permissions"
                            class="mr-6px w-14px h-14px"
                          />
                          <svg-icon
                            v-if="item === 'resetpwd'"
                            icon-class="resetpwd"
                            class="mr-6px w-14px h-14px"
                          />
                          <svg-icon
                            v-if="item === 'addstock'"
                            icon-class="addstock"
                            class="mr-6px w-14px h-14px"
                          />
                          {{
                            item === "addstock"
                              ? $t("common.addstock")
                              : item === "resetpwd"
                                ? $t("common.resetpwd")
                                : item === "permissions"
                                  ? $t("common.permissions")
                                  : item === "edit"
                                    ? editRowId == scope.row.id
                                      ? $t("common.save")
                                      : $t("common.edit")
                                    : item === "view"
                                      ? col.operatText && col.operatText["view"]
                                        ? col.operatText["view"]
                                        : $t("common.view")
                                      : $t("common.delete")
                          }}
                        </el-button>
                      </template>
                    </template>
                    <!-- 其他 -->
                    <template v-else-if="typeof item === 'object'">
                      <template v-if="item.auth">
                        <el-button
                          v-hasPerm="[`${contentConfig.pageName}:${item.auth}`]"
                          :icon="item.icon"
                          type="primary"
                          link
                          @click="
                            handleOperat({
                              name: item.name,
                              row: scope.row,
                              column: scope.column,
                              $index: scope.$index,
                            })
                          "
                        >
                          {{ item.text }}
                        </el-button>
                      </template>
                      <template v-else>
                        <el-button
                          :icon="item.icon"
                          type="primary"
                          link
                          @click="
                            handleOperat({
                              name: item.name,
                              row: scope.row,
                              column: scope.column,
                              $index: scope.$index,
                            })
                          "
                        >
                          {{ item.text }}
                        </el-button>
                      </template>
                    </template>
                  </template>
                </template>
              </el-table-column>
            </template>
            <!-- 自定义 -->
            <template v-else-if="col.templet === 'custom'">
              <el-table-column
                :show-overflow-tooltip="col.tooltip"
                :min-width="col.minWidth"
                v-bind="col"
              >
                <template #default="scope">
                  <slot
                    :name="col.slotName ?? col.prop"
                    :prop="col.prop"
                    v-bind="scope"
                  ></slot>
                </template>
              </el-table-column>
            </template>
            <!-- 其他 -->
            <template v-else>
              <el-table-column
                :show-overflow-tooltip="col.tooltip"
                :min-width="col.minWidth"
                v-bind="col"
              />
            </template>
          </template>
        </el-table>
      </div>
      <!-- 分页 -->
      <pagination
        v-if="total > 0 && showPagination"
        v-model:total="total"
        v-model:page="queryParams.page"
        v-model:limit="queryParams.page_size"
        @pagination="handlePagination"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { Search } from "@element-plus/icons-vue";
import { ref, reactive } from "vue";
import Pagination from "@/components/Pagination/index.vue";
import type { TableProps } from "element-plus";
import { useI18n } from "vue-i18n";
import { useTransition, TransitionPresets } from "@vueuse/core";
import type { EpPropMergeType } from "element-plus/es/utils/vue/props/types";
// 对象类型
export type IObject = Record<string, any>;
// 定义接收的属性
export interface IOperatData {
  name: string;
  row: any;
  column: any;
  $index: number;
}
export interface ITag {
  label: string;
  value: number | string;
}
export interface IContentConfig<T = any> {
  // 页面名称(参与组成权限标识,如sys:user:xxx)
  tagList?: ITag[];
  searchPlaceholder?: string;
  hasDashData: boolean;
  pageName: string;
  tableName?: string;
  // table组件属性
  table?: Omit<TableProps<any>, "data">;
  // 列表的网络请求函数(需返回promise)
  indexAction: (queryParams: T) => Promise<any>;
  // 删除的网络请求函数(需返回promise)
  deleteAction?: (ids: Ids) => Promise<any>;
  // 导出的网络请求函数(需返回promise)
  exportAction?: (queryParams: T) => Promise<any>;
  // 主键名(默认为id)
  pk?: string;
  // 表格工具栏(默认支持refresh,add,delete,export,也可自定义)
  toolbar: (
    | "refresh"
    | "add"
    | "delete"
    | "export"
    | {
        auth?: string;
        icon?: string;
        name: string;
        text: string;
      }
  )[];
  searchbar?: (
    | "add"
    | "delete"
    | {
        auth?: string;
        icon?: string;
        name: string;
        text: string;
      }
  )[];
  // table组件列属性(额外的属性templet,operat,slotName)
  cols: IObject[];
}
const props = withDefaults(
  defineProps<{
    contentConfig: IContentConfig;
    stripe?: boolean;
    showPagination?: boolean;
    pageSize?: number;
    editRowId?: string;
    defaultParams?: IObject;
    isTree?: boolean;
  }>(),
  {
    stripe: false,
    showPagination: true,
    pageSize: 10,
    editRowId: "",
    isTree: false,
    defaultParams: () => {
      return {};
    },
  }
);

const { t } = useI18n();
// 定义自定义事件
const emit = defineEmits<{
  addClick: [];
  exportClick: [];
  toolbarClick: [name: string];
  editClick: [row: IObject];
  permissionsClick: [row: IObject];
  resetpwdClick: [row: IObject];
  addstockClick: [row: IObject];
  viewClick: [row: IObject];
  operatClick: [data: IOperatData];
  searchClick: [data: IObject];
  deleteClick: [id: string];
}>();

// 主键
const pk = props.contentConfig.pk ?? "id";
// 加载状态
const loading = ref(false);
// 删除ID集合 用于批量删除
const removeIds = ref<(number | string)[]>([]);
// 数据总数
const total = ref(0);
// 列表数据
const pageData = ref<IObject[]>([]);
// 搜索参数
const queryParams = reactive<IObject>({
  page: 1,
  page_size: props.pageSize,
});
const searchName = ref("");
const tag = ref<number | string>(0);
// 上一次搜索条件
let lastFormData = {};
// 获取分页数据
function fetchPageData(formData: IObject = {}, isRestart = false) {
  loading.value = true;
  lastFormData = formData;
  console.log("%c Line:467 🧀 lastFormData", "color:#6ec1c2", lastFormData);
  if (isRestart) {
    if (props.contentConfig.tagList && props.contentConfig.tagList.length > 0) {
      tag.value = props.contentConfig?.tagList[0].value;
    }
    queryParams.page = 1;
    queryParams.page_size = props.pageSize;
  }
  props.contentConfig
    .indexAction({ ...queryParams, ...formData, ...props.defaultParams })
    .then((data) => {
      if (props.isTree) {
        total.value = 0;
        pageData.value = data;
      } else {
        total.value = data.total;
        pageData.value = data.list;
      }
      // 面板数据
      if (props.contentConfig.hasDashData && data.nums) {
        totalTasksCount.value = data.nums.total_num;
        tasksProgressCount.value = data.nums.ing_num;
        completedTasksCount.value = data.nums.finish_num;
      }
    })
    .finally(() => {
      loading.value = false;
    });
}
fetchPageData();
const params: IObject = {};
const handleStatus = (value: number | string) => {
  tag.value = value;
  params["status"] = value;
  fetchPageData(params, false);
  // emit("searchClick", {
  //   prop: "status",
  //   value: value,
  // });
};
const handleSearch = () => {
  params["keyword"] = searchName.value;
  fetchPageData(params, true);
  // emit("searchClick", {
  //   prop: "keyword",
  //   value: searchName.value,
  // });
};
// 行选中
function handleSelectionChange(selection: any[]) {
  removeIds.value = selection.map((item) => item[pk]);
}
// 刷新
function handleRefresh() {
  fetchPageData({}, true);
}
// 删除
function handleDelete(id?: number | string) {
  if (id == "-1") {
    pageData.value.pop();
    emit("deleteClick", id);
    return;
  }
  const ids = [id || removeIds.value].join(",");
  if (!ids) {
    ElMessage.warning(t("common.checkDeleteOption"));
    return;
  }

  ElMessageBox.confirm(t("common.confirmDeletion"), t("common.warning"), {
    confirmButtonText: t("common.confirm"),
    cancelButtonText: t("common.cancel"),
    type: "warning",
  }).then(function () {
    if (props.contentConfig.deleteAction) {
      props.contentConfig.deleteAction({ ids: [ids] }).then(() => {
        ElMessage.success(t("common.deleteSuccessful"));
        handleRefresh();
      });
    } else {
      ElMessage.error("未配置deleteAction");
    }
  });
}
// 分页
function handlePagination() {
  fetchPageData(lastFormData);
}
// 操作栏
function handleToolbar(name: string) {
  switch (name) {
    case "refresh":
      handleRefresh();
      break;
    case "add":
      emit("addClick");
      break;
    case "delete":
      handleDelete();
      break;
    case "export":
      emit("exportClick");
      break;
    default:
      emit("toolbarClick", name);
      break;
  }
}
// 操作列
function handleOperat(data: IOperatData) {
  switch (data.name) {
    case "edit":
      emit("editClick", data.row);
      break;
    case "permissions":
      emit("permissionsClick", data.row);
    case "resetpwd":
      emit("resetpwdClick", data.row);
      break;
    case "addstock":
      emit("addstockClick", data.row);
      break;
    case "view":
      emit("viewClick", data.row);
      break;
    case "delete":
      handleDelete(data.row[pk]);
      break;
    default:
      emit("operatClick", data);
      break;
  }
}
// 导出Excel
function exportPageData(queryParams: IObject = {}) {
  if (props.contentConfig.exportAction) {
    props.contentConfig.exportAction(queryParams).then((response) => {
      const fileData = response.data;
      const fileName = decodeURI(
        response.headers["content-disposition"].split(";")[1].split("=")[1]
      );
      const fileType =
        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8";

      const blob = new Blob([fileData], { type: fileType });
      const downloadUrl = window.URL.createObjectURL(blob);
      const downloadLink = document.createElement("a");
      downloadLink.href = downloadUrl;
      downloadLink.download = fileName;
      document.body.appendChild(downloadLink);
      downloadLink.click();
      document.body.removeChild(downloadLink);
      window.URL.revokeObjectURL(downloadUrl);
    });
  } else {
    ElMessage.error("未配置exportAction");
  }
}

const duration = 5000;
// 任务总数
const totalTasksCount = ref(0);
const totalTasksCountOutput = useTransition(totalTasksCount, {
  duration: duration,
  transition: TransitionPresets.easeOutExpo,
});
totalTasksCount.value = 0;

// 正在进行任务
const tasksProgressCount = ref(0);
const tasksProgressCountOutput = useTransition(tasksProgressCount, {
  duration: duration,
  transition: TransitionPresets.easeOutExpo,
});
tasksProgressCount.value = 0;

// 已完成任务
const completedTasksCount = ref(0);
const completedTasksCountOutput = useTransition(completedTasksCount, {
  duration: duration,
  transition: TransitionPresets.easeOutExpo,
});
completedTasksCount.value = 0;

interface CardProp {
  title: string;
  tagType: EpPropMergeType<
    StringConstructor,
    "primary" | "success" | "info" | "warning" | "danger",
    unknown
  >;
  count: any;
  bgClass: string;
  iconClass: string;
}
// 卡片数量
const cardData = ref<CardProp[]>([
  {
    title: t("dashboard.totalTasks"),
    tagType: "success",
    count: totalTasksCountOutput,
    bgClass: "bg01",
    iconClass: "task-data-icon1",
  },
  // {
  //   title: t("dashboard.totalWbs"),
  //   tagType: "success",
  //   count: tasksProgressCountOutput,
  //   bgClass: "bg02",
  //   iconClass: "task-data-icon2",
  // },
  {
    title: t("dashboard.tasksProgress"),
    tagType: "success",
    count: tasksProgressCountOutput,
    bgClass: "bg03",
    iconClass: "task-data-icon3",
  },
  {
    title: t("dashboard.completedTasks"),
    tagType: "success",
    count: completedTasksCountOutput,
    bgClass: "bg04",
    iconClass: "task-data-icon4",
  },
]);

// 暴露的属性和方法
defineExpose({ fetchPageData, exportPageData, pageData });
</script>

<style lang="scss" scoped>
.table-box {
  // margin-top: 24px;
  padding: 24px 24px 32px;
  background: #fff;
  border-radius: 4px;
  .table-tool {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-bottom: 16px;
    .table-title {
      display: flex;
      align-items: center;
      color: #323233;
      font-family: "PingFang SC";
      font-size: 16px;
      font-weight: 900;
      text-transform: capitalize;
      &::before {
        content: "";
        display: inline-block;
        width: 3px;
        height: 22px;
        margin-right: 8px;
        background: #4e6bef;
      }
    }
  }
}
.el-row {
  .el-col {
    position: relative;
    &::before {
      display: block;
      content: "";
      position: absolute;
      width: 1px;
      height: 60px;
      background: #ebedf0;
      left: 0;
      top: 50%;
      transform: translateY(-50%);
    }
    &:first-child::before {
      display: none;
    }
  }
}

.state-item {
  height: 125px;
  padding: 24px 48px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;

  .state-right {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    span {
      display: flex;
      height: 27px;
      flex-shrink: 0;
      color: #6e6e86;
      font-size: 14px;
    }
  }
  .state-left {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    span {
      display: flex;
      height: 27px;
      flex-shrink: 0;
      color: #6e6e86;
      font-size: 14px;
      font-weight: 400;
    }
    strong {
      flex-shrink: 0;
      display: flex;
      height: 50px;
      align-items: center;
      color: #4b4b66;
      font-size: 36px;
      font-weight: 900;
    }
  }
  .svg-icon {
    width: 100px !important;
    height: 100px !important;
  }
}
</style>
